; 本程序实现输出Hello Bochs的打印
; 在Linux下编译链接成ELF文件格式
; 编译链接方法：
;   nasm -f elf64 elf_helloworld.asm -o helloworld.o
;   ld -s helloworld.o -o helloworld
;   ./helloworld

extern choose

[SECTION .data]
DispMsg     db      "Hello Bochs!", 0Ah
DispMsgLen  equ     $ - DispMsg

[SECTION .text]
global _start           ; 链接器需要识别_start符号，所以必须导出
global print

_start:
    mov edx, DispMsgLen
    mov ecx, DispMsg
    mov ebx, 1
    mov eax, 4              ; sys_write
    int 080h

    mov ebx, 0
    mov eax, 1              ; sys_exit
    int 080h


{
    "llvm-target": "i386-unknown-none",
    "data-layout": "e-m:e-i32:32-p:32:8-n32-S128",
    "arch": "x86-64",
    "target-endian": "little",
    "target-pointer-width": "32",
    "target-c-int-width": "32",
    "os": "none",
    "executables": true,
    "linker-flavor": "ld.lld",
    "linker": "rust-lld",
    "panic-strategy": "abort",
    "disable-redzone": true,
    "features": "-mmx,-sse,+soft-float"
}



ENTRY(_start)   /* 内核入口点：bootloader执行完后会跳到此处执行 */

; tags域，可选，此处没有
    dw 3
    dw 0
    dd 12
    dd _start

/* 可执行文件有两个节：.boot和.text，需要保证.boot在.text之前 */
SECTIONS {
    . = 1M;      /* 第一个节加载到地址1M处，意味着内核被加载到内存的地址 */
    
    .boot :     /* 注意： .boot和:之间有空格 */
    {
        /* 需要保证grub引导能在内核镜像的最开始处找到multiboot_header */
        *(.multiboot_header)
    }

    /* 其他所有节在此处 */
    .text :     /* 注意： .text和:之间有空格 */
    {
        *(.text)
    }
}


    xor eax, eax
    mov ax, ss
    call DispReturn
    call DispInt

    sgdt [_gdt_base]
    xor eax, eax
    mov eax, [_gdt_base + 2]
    call DispReturn
    call DispInt

    mov eax, [_gdt_base + 2]
    xor edx, edx
    mov dx, ss
    and dx, 0FFF8h
    add edx, eax
    mov eax, [edx]
    call DispReturn
    call DispInt

    mov eax, [edx + 4]
    call DispReturn
    call DispInt